<?php
/**
 * Created by PhpStorm.
 * User: liuxiaojie
 * Date: 2019-02-24
 * Time: 12:15
 */

namespace app\service;

use app\exception\CustomException;
use app\model\AcceptOrder;
use app\model\Config;
use app\model\Customer;
use app\model\MoneyLog;
use app\model\RechargeConfig;
use app\model\RechargeOrder;
use app\model\RepairOrder;
use app\model\RepairPerson;
use app\model\ServiceConfig;
use app\tools\Helper;
use app\tools\MIniprogram;
use app\tools\RedisCache;
use app\tools\Wx;
use think\Db;
use think\Exception;

class OrderService extends BaseService{


    function __construct()
    {
        parent::__construct();
    }

    function confirm($data)
    {
        $order_no = Helper::createOrderSn();
        $serial_no = $order_no.rand(10000, 99999);
        $time = time();

        $pay_money = ServiceConfig::where(['id'=> $data['type']])->field('terrace_money, commission, earnest_money')->find();
        $total_money = $pay_money['terrace_money'] + $pay_money['commission'] + $pay_money['earnest_money'];
        $arr = explode(',', $data['images']);
        $goods_insert = [
            "details"=> $data['details'],
            "img_arr"=> $data['images'],
            "images"=> $arr[0],
            "mobile"=> $data['mobile'],
            "address"=> $data['address'],
            "customer_id"=> $data['customer_id'],
            "lat"=> $data['lat'],
            "lng"=> $data['lng'],
            "order_no"=> $order_no,
            "pay_money"=> $total_money,
            "serial_no"=> $serial_no,
            "add_time"=> date("Y-m-d H:i:s", $time),
            "trade_no"=> '',
            "status"=> 10,
            'type'=> $data['type'],
            'master_id'=> $data['master_id'],
            'sheet_type'=> $data['master_id']?1:0
        ];

        if($data['is_money'])
        {
            $money = db('customer')->where(['id'=> $data['customer_id']])->value('money_xn');
            if($money < $total_money)
            {
                throw new CustomException("MONEY_NOT_ENOUGH");
            }
            $goods_insert['status'] = 20;

            Db::startTrans();
            try{
                $o_id = RepairOrder::insertGetId($goods_insert);
                if($total_money > 0)
                {
                    db('customer')->where(['id'=> $data['customer_id']])->setDec('money_xn', $total_money);
                    MoneyLog::addLog([
                        "child_id"=> 0,
                        "u_id"=> $data['customer_id'],
                        "type"=> 1,
                        "value"=> -$total_money,
                        "reason_type"=> 9
                    ]);
                }

                Db::commit();
            }catch (CustomException $exception){
                Db::rollback();
                throw new CustomException();
            }

            $wx = new Wx();
            if($goods_insert['sheet_type'] == 1)
            {
                $unionid = db('customer')->where(['id'=> $goods_insert['master_id']])->value('unionid');
                $openid = db('customer')->where(['unionid'=> $unionid, 'type'=> 2])->value('openid');
                $wx->sendTemplate([
                    'openid'=> $openid,
                    'template_id'=> 'VkOPusrnpM5ueEl1WCcS9Pf7CBghPYMmWtkSrsCn9Ao',
                    'page'=> 'pages/repair/worker/order/order',
                    'data'=>[
                        "first"=> [
                            "value"=> $goods_insert['details'],
                        ],
                        "keyword1"=> [
                            "value"=> $goods_insert['order_no'],
                        ],
                        "keyword2"=> [
                            "value"=> date('Y-m-d H:i:s'),
                        ],
                    ]
                ]);

                db('repair_order')->where(['id'=> $o_id])->update(['is_tui'=> 1]);
            }

            $wx->sendTemplate([
                'openid'=> 'oVKH41ZAzmuGlUaJqY_S-VHrTsxA',
                'template_id'=> 'VkOPusrnpM5ueEl1WCcS9Pf7CBghPYMmWtkSrsCn9Ao',
                'page'=> '',
                'data'=>[
                    "first"=> [
                        "value"=> $goods_insert['details'],
                    ],
                    "keyword1"=> [
                        "value"=> $goods_insert['order_no'],
                    ],
                    "keyword2"=> [
                        "value"=> date('Y-m-d H:i:s'),
                    ],
                ]
            ]);


        }else{
            $o_id = RepairOrder::insertGetId($goods_insert);
        }

        return [
            'total'=> $total_money,
            'serial_no'=> $serial_no
        ];
    }

    function acceptOrder($data = [])
    {
        $status = RepairOrder::where(['id'=> $data['o_id']])->field('status, type, customer_id')->find();
        if($status['status'] != 20)
        {
            throw new CustomException("ORDER_HAS_ACCEPTED");
        }

        $value = ServiceConfig::where(['id'=> $status['type']])->value('diam');
        $star = AcceptOrder::where(['customer_id'=> $data['customer_id'], 'star'=> ['>', 0]])->sum('star');

        $count = AcceptOrder::where(['customer_id'=> $data['customer_id'], 'status'=> ['<>', 40]])->count();
        switch (true)
        {
            case $star < 15:
                if($count >= 999999)
                {
                    echo json_encode([
                        "errno" => 100042,
                        "errmsg" => "当前等级只能同时接1个订单",
                        "statusCode"=> 200,
                        "data" => $data
                    ], JSON_UNESCAPED_UNICODE);die();
                }
                break;
            case $star < 500:
                $value = ceil($value*0.9);
                break;
            case $star < 5000:
                if($count >= 999999)
                {
                    echo json_encode([
                        "errno" => 100042,
                        "errmsg" => "当前等级只能同时接2个订单",
                        "statusCode"=> 200,
                        "data" => $data
                    ], JSON_UNESCAPED_UNICODE);die();
                }
                $value = ceil($value*0.7);
                break;
            default:
                if($count >= 999999)
                {
                    echo json_encode([
                        "errno" => 100042,
                        "errmsg" => "当前等级只能同时接2个订单",
                        "statusCode"=> 200,
                        "data" => $data
                    ], JSON_UNESCAPED_UNICODE);die();
                }
                $value = ceil($value*0.4);
                break;

        }
        $diam = Customer::where(['id'=> $data['customer_id']])->value('diam');
        if($diam<$value)
        {
            throw new CustomException("DIAM_NOT_ENOUGH");
        }

        Db::startTrans();
        try{
            $info = RepairPerson::where(['customer_id'=> $data['customer_id']])->field('name, mobile')->find();
            $data['name'] = $info['name'];
            $data['mobile'] = $info['mobile'];
            $data['status'] = 30;
            $money = ServiceConfig::where(['id'=> $status['type']])->field('earnest_money, commission')->find();
            $data['earnest_money'] = $money['earnest_money'];
            $data['commission'] = $money['commission'];
            AcceptOrder::insertGetId($data);
            RepairOrder::where(['id'=> $data['o_id']])->update(['status'=> 30]);
            Customer::where(['id'=> $data['customer_id']])->setDec("diam", $value);
            MoneyLog::addLog([
                'child_id'=> 0,
                'u_id'=> $data['customer_id'],
                'type'=> 3,
                'value'=> -$value,
                'reason_type'=> 6
            ]);
            Db::commit();
        }catch (Exception $exception){
            Db::rollback();
            throw new CustomException();
        }

        $form = db('form_data')->where(['customer_id'=> $status['customer_id']])->field('form_id, openid, id')->order('create_time desc')->find();
        MIniprogram::sendTemplate([
            'openid'=> $form['openid'],
            'template_id'=> 'lIvvdVzON5WfLNJEbGVJpSh8GOrzpRLTC1EJsPfRsgI',
            'form_id'=> $form['form_id'],
            'page'=> 'pages/repair/openRepair/openRepair',
            'data'=> [
                'keyword1'=> ['value'=> "您的订单已被接受！！"],
                'keyword2'=> ['value'=> $data['name']],
                'keyword3'=> ['value'=> date('Y-m-d H:i:s')],
                'keyword4'=> ['value'=> $data['mobile']],
            ]
        ]);
        db('form_data')->where(['id'=> $form['id']])->delete();

    }

    function orderCancel($id = 0)
    {
        $status = RepairOrder::where(['id'=> $id])->field('status, customer_id, pay_money')->find();
        if($status['status'] != 20)
        {
            throw new CustomException("ORDER_NOT_CANCEL");
        }

        $key = "cancelOrders_uid_".$status['customer_id'];
        if(RedisCache::getInstance()->get($key))
        {
            throw new CustomException("OPERATION_OFTEN");
        }
        RedisCache::getInstance()->set($key, 1);
        Db::startTrans();
        try
        {
            RepairOrder::where(['id'=> $id])->delete();
            db('customer')->where(['id'=> $status['customer_id']])->setInc('money', $status['pay_money']);
            MoneyLog::addLog([
                "child_id"=> 0,
                "u_id"=> $status['customer_id'],
                "type"=> 1,
                "value"=> $status['pay_money'],
                "reason_type"=> 8
            ]);
            Db::commit();
        }catch (CustomException $exception){
            Db::rollback();
            RedisCache::getInstance()->delete($key);
            throw new CustomException();
        }
        RedisCache::getInstance()->delete($key);
        return true;
    }

    function orderEdit($data = [])
    {
        $status = RepairOrder::where(['id'=> $data['id']])->value('status');
        if($status != 20)
        {
            throw new CustomException("ORDER_NOT_EDIT");
        }
        $arr = explode(',', $data['images']);
        $goods_insert = [
            "id"=> $data['id'],
            "details"=> $data['details'],
            "img_arr"=> $data['images'],
            "images"=> $arr[0],
            "mobile"=> $data['mobile'],
            "address"=> $data['address'],
            "customer_id"=> $data['customer_id'],
            "lat"=> $data['lat'],
            "lng"=> $data['lng'],
            "add_time"=> date("Y-m-d H:i:s"),
        ];

        $o_id = RepairOrder::update($goods_insert);
    }

    function orderHistory($data = [], $pageSize = 10)
    {
        $lat = $data['lat'];
        $lng = $data['lng'];

        $where = [
            'a.customer_id'=> $data['customer_id'],
        ];

        if($data['status'] == 40) $where['o.status'] = 40;
        else $where['o.status'] = ['<', 40];

        $list = AcceptOrder::alias('a')
            ->join('repair_order o', 'a.o_id = o.id')
            ->join('service_config s', 's.id = o.type')
            ->where($where)
            ->field("o.pay_money, o.id as o_id, a.id, o.details, s.name, o.type, o.images, o.address, o.status as o_status, o.order_no, a.status as a_status, o.add_time, a.add_time as a_add_time,(st_distance (point (o.lng, o.lat),point($lng,$lat) ) * 111195) AS distance, o.mobile")
            ->order('a.id desc')
            ->paginate($pageSize)->each(function (&$item){
                if(intval($item['distance']) < 1000)
                {
                    $item['distance'] = intval($item['distance']).'m';
                }else{
                    $item['distance'] = round(intval($item['distance'])/1000, 2).'km';
                }
            });

        return $list;

    }

    function orderAvailable($data = [], $pageSize = 10)
    {
        $lat = $data['lat'];
        $lng = $data['lng'];

        $where = [
            'customer_id'=> $data['customer_id'],
        ];

        $distance = RepairPerson::where($where)->value('distance');

        $where = [
//            'distance'=> ['<=', $distance],
            'r.status'=> 20
        ];

//        $value = Config::where(['type'=> 2])->value('value');

        $list = RepairOrder::alias('r')
            ->join('service_config s', 's.id = r.type')
            ->where($where)
            ->where("(st_distance (point (r.lng, r.lat),point($lng,$lat) ) * 111195) <= $distance")
            ->field("s.diam as value, r.id, r.pay_money, r.type, s.name, r.details, r.images, r.address, r.status as o_status, r.add_time, (st_distance (point (r.lng, r.lat),point($lng,$lat) ) * 111195) AS distance, r.mobile")
            ->order('r.id desc')
            ->paginate($pageSize)->each(function (&$item){
                if(intval($item['distance']) < 1000)
                {
                    $item['distance'] = intval($item['distance']).'m';
                }else{
                    $item['distance'] = round(intval($item['distance'])/1000, 2).'km';
                }
//                $item['value'] = $value;
            });

        return $list;

    }

    function orderAvailable2($data = [], $pageSize = 10)
    {
        $lat = $data['lat'];
        $lng = $data['lng'];

        $where = [
            'customer_id'=> $data['customer_id'],
        ];

        $distance = RepairPerson::where($where)->value('distance');

        $where = [
//            'distance'=> ['<=', $distance],
            'r.status'=> 20,
            'r.sheet_type'=> ['>', 0]
        ];

        $where2 = "r.master_id = {$data['customer_id']} and r.sheet_type = 1 or r.sheet_type = 2";

//        $value = Config::where(['type'=> 2])->value('value');

        $list = RepairOrder::alias('r')
            ->join('service_config s', 's.id = r.type')
            ->where($where)
            ->where($where2)
            ->where("(st_distance (point (r.lng, r.lat),point($lng,$lat) ) * 111195) <= $distance")
            ->field("s.diam as value, r.id, r.pay_money, r.type, s.name, r.details, r.images, r.address, r.status as o_status, r.add_time, (st_distance (point (r.lng, r.lat),point($lng,$lat) ) * 111195) AS distance, r.mobile")
            ->order('r.id desc')
            ->paginate($pageSize)->each(function (&$item){
                if(intval($item['distance']) < 1000)
                {
                    $item['distance'] = intval($item['distance']).'m';
                }else{
                    $item['distance'] = round(intval($item['distance'])/1000, 2).'km';
                }
//                $item['value'] = $value;
            });

        return $list;

    }

    function orderDetail($id, $uid = 0, $lat, $lng)
    {
        $data = RepairOrder::alias('o')
            ->join('accept_order a', 'a.o_id = o.id', 'left')
            ->join('repair_person p', 'p.customer_id = a.customer_id', 'left')
            ->where(['o.id'=> $id])
            ->field("p.avatar, p.fullname, a.customer_id, o.img_arr, (st_distance (point (o.lng, o.lat),point($lng,$lat) ) * 111195) AS distance, o.order_no, a.star, a.eva, o.type, o.add_time, a.add_time as a_add_time, o.status, o.details, o.id, o.images, o.pay_money, o.mobile, o.address, o.lat, o.lng, p.mobile as a_mobile")
            ->find();
        $value1 = ServiceConfig::where(['id'=> $data['type']])->value('earnest_money');

        $value = ServiceConfig::where(['id'=> $data['type']])->value('diam');
        if($uid)
        {
            $star = AcceptOrder::where(['customer_id'=> $uid, 'star'=> ['>', 0]])->sum('star');
            switch (true)
            {
                case $star < 15:
                    break;
                case $star < 500:
                    $value = ceil($value*0.9);
                    break;
                case $star < 5000:
                    $value = ceil($value*0.7);
                    break;
                default:
                    $value = ceil($value*0.4);
                    break;

            }
        }

        if($data['customer_id'])
        {
            $star = AcceptOrder::where(['customer_id'=> $data['customer_id'], 'uid'=> ['>', 0]])->field("sum(star) as star, count(id) as num")->find();
//            dump($star);
            if($star['star'])
            {
                $data['score'] = intval($star['star']/$star['num']);
            }else{
                $data['score'] = 0;
            }

        }

        $data['value'] = $value;
        $data['img_arr'] = explode(',', $data['img_arr']);
        if(intval($data['distance']) < 1000)
        {
            $data['distance'] = intval($data['distance']);
        }else{
            $data['distance'] = round(intval($data['distance'])/1000, 2).'k';
        }
        $data['earnest_money'] = $value1;
        return $data;
    }

    function my($uid = 0)
    {
        $data = RepairPerson::where(['customer_id'=> $uid])->field('address, status, fullname as name, service_type, avatar')->find();
        $service = ServiceConfig::where(['id'=> ['in', explode(',', $data['service_type'])]])->field('id as service_type, name as service, icon')->select();
        $data['service'] = $service;

        $count = AcceptOrder::alias('a')
            ->join('repair_order o', 'a.o_id = o.id')
            ->where(['a.customer_id'=> $uid, 'a.status'=> 40])
            ->count();

        $info = AcceptOrder::alias('a')
            ->join('repair_order o', 'a.o_id = o.id')
            ->where(['a.customer_id'=> $uid, 'star'=> ['>', 0]])
            ->field('sum(a.star) as stars, count(a.id) as num')
            ->find();
        if($info['stars'])
        {
            $star = round($info['stars']/$info['num'], 1);
        }else{
            $star = 0;
        }
        $data['star'] = $star;
        $data['total_star'] = $info['stars']?:0;
        $data['total'] = $count;
        switch (true)
        {
            case $data['total_star'] < 15:
                $name = '铜牌师傅';
                break;
            case $data['total_star'] < 500:
                $name = '银牌师傅';
                break;
            case $data['total_star'] < 5000:
                $name = '金牌师傅';
                break;
            default:
                $name = '钻石师傅';
                break;

        }
        $data['designation'] = $name;

        return $data;
    }

    function recharge($data = [])
    {
        $diam = RechargeConfig::where(['id'=> $data['id']])->find();
        Db::startTrans();
        try
        {
            $order_no = Helper::createOrderSn();
            $serial_no = $order_no.rand(10000, 99999);

            $post = [
                'order_no'=> $order_no,
                'serial_no'=> $serial_no,
                'diam'=> $diam['num'],
                'price'=> $diam['price'],
                'status'=> 10,
                'customer_id'=> $data['customer_id']
            ];
            RechargeOrder::insert($post);
            Db::commit();
        }catch (Exception $exception){
//            echo $exception->getMessage();
            Db::rollback();
            throw new CustomException();
        }

        return [
            'total'=> $diam['price'],
            'serial_no'=> $serial_no
        ];
    }

    function serviceEdit($data = [])
    {
        $info = RepairPerson::where(['customer_id'=> $data['customer_id']])->field('status, id')->find();
        if($info['status'] != 3)
        {
//            throw new CustomException("AUTH_FAIL");
        }
        $value = 100;
        $diam = Customer::where(['id'=> $data['customer_id']])->value('diam');
        if($diam<$value)
        {
            throw new CustomException("DIAM_NOT_ENOUGH");
        }

        Db::startTrans();
        try{
            RepairPerson::where(['id'=> $info['id']])->update(['service_type'=> $data['type']]);
            Customer::where(['id'=> $data['customer_id']])->setDec("diam", $value);
            MoneyLog::addLog([
                'child_id'=> 0,
                'u_id'=> $data['customer_id'],
                'type'=> 3,
                'value'=> -$value,
                'reason_type'=> 7
            ]);
            Db::commit();
        }catch (Exception $exception){
            Db::rollback();
            throw new CustomException();
        }
    }

    function evaluate($data = [])
    {
        $info = AcceptOrder::where(['o_id'=> $data['o_id']])->field('status, id, customer_id')->find();
        if($info['status'] != 40)
        {
            throw new CustomException("ORDER_NOT_COMPLETED");
        }
        AcceptOrder::where(['id'=> $info['id']])->update(['star'=> $data['star'], 'eva'=> $data['eva'], 'uid'=> $data['uid'], 'eva_date'=> date('Y-m-d')]);

        $unionid = \db('customer')->where(['id'=> $info['customer_id']])->value('unionid');
        $wx = new Wx();
        $openid = db('customer')->where(['unionid'=> $unionid, 'type'=> 2])->value('openid');
        $wx->sendTemplate([
            'openid'=> $openid,
            'template_id'=> 'lUcxWmFsFXWRuA8MKbh2DYwpImBMU-Mz0lnkuSfHZSQ',
            'page'=> 'pages/repair/worker/workerCenter/workerCenter',
            'data'=>[
                "first"=> [
                    "value"=> "客户对您进行了评价，开来查看吧！！",
                ],
                "keyword1"=> [
                    "value"=> '匿名',
                ],
                "keyword2"=> [
                    "value"=> date('Y-m-d H:i:s'),
                ],
                "keyword3"=> [
                    "value"=> $data['star'],
                ],
                "keyword4"=> [
                    "value"=> '',
                ],
            ]
        ]);
        return true;
    }
}